﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;

using Seven.Entity;
using Seven.DataModel.RepositoryModels.UserAbout;
using Seven.DataModel.ViewModels.UserAbout;
using Seven.Tools.Extension;
using Seven.Tools.Helper;

namespace Seven.Service.Powerful
{
    public partial class SysUserMenuPermissionService
    {
        #region 提供json数据

        /// <summary>
        /// 获取用户菜单权限数据
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <param name="rangeFilter">是否根据管理范围过滤</param>
        /// <returns></returns>
        public JsonResult UserMenuPermissionGrid(int userId, bool rangeFilter)
        {
            IEnumerable<SysMenu> range;
            IEnumerable<int> menuIds;
            if (rangeFilter)
            {
                range = CurrentUserMenuRange;
            }
            else
            {
                using (var unit = DbFactory.UnitOfWork)
                {
                    var menuRep = unit.SysMenu;
                    range = menuRep.GetAllMenus();
                }
            }
            if (range.Count() > 0)
            {
                range = range.OrderBy(o => o.SortNumber);
                menuIds = range.Where(w => !string.IsNullOrWhiteSpace(w.ControllerName) && !string.IsNullOrWhiteSpace(w.ActionName)).Select(s => s.ID);
            }
            else { return new DataResult(new List<object>()).SerializeToJsonResult(); }
            using (var unit = DbFactory.UnitOfWork)
            {
                var rep = unit.SysUserMenuPermission;
                var data = rep.UserMenuPermissionGrid(userId, menuIds, true).ToList();
                var otherData = this.GetCurrentMenuPermissionRangeByMenuIDs(menuIds);
                var tempIds = data.Select(s => s.MenuPermissionID);
                //组建无用户权限记录的默认用户权限数据
                foreach (var item in otherData.Where(w => !tempIds.Contains(w.ID)))
                {
                    data.Add(new UserMenuPermissionGridModel
                    {
                        UserID = userId,
                        MenuPermissionID = item.ID,
                        Check = true,
                        Indeterminate = true,
                        MenuPermissionName = item.Name,
                        MenuPermissionSortNumber = item.SortNumber,
                        MenuID = item.MenuID
                    });
                }
                data = data.TryOrderBy(o => o.MenuPermissionSortNumber).ToList();

                return new DataResult(range.Select(s => new
                {
                    s.ID,
                    s.Name,
                    iconCls = string.IsNullOrWhiteSpace(s.IconCls) ? SiteCore.DefaultIconClassName : s.IconCls,
                    s.ParentID,
                    Permissions = data.Where(w => w.MenuID == s.ID).Select(ss => new { ss.MenuPermissionID, ss.MenuPermissionName, State = GetCheckboxState(ss.Check, ss.Indeterminate) })
                })).SerializeToJsonResult();
            }
        }

        public IEnumerable<SysMenuPermission> GetCurrentMenuPermissionRangeByMenuIDs(IEnumerable<int> menuIds)
        {
            if (menuIds.Count() == 0) { return Enumerable.Empty<SysMenuPermission>(); }
            var range = CurrentUserMenuPermissionRange;
            return range.Where(w => menuIds.Contains(w.MenuID));
        }

        #endregion

        #region CUD操作

        /// <summary>
        /// 保存用户权限
        /// </summary>
        /// <param name="models">权限数据模型</param>
        /// <param name="userId">用户ID</param>
        /// <param name="otherUserIds">应用到其他用户ids</param>
        /// <returns></returns>
        public JsonResult SaveUserPermission(IEnumerable<PermissionModel> models, int userId, string otherUserIds)
        {
            using (var unit = DbFactory.UnitOfWork)
            {
                #region 用户权限组装

                var rep = unit.SysUserMenuPermission;
                var oldPermission = rep.GetUserMenuPermissions(userId);

                IList<SysUserMenuPermission> inserts = new List<SysUserMenuPermission>();
                IList<SysUserMenuPermission> updates = new List<SysUserMenuPermission>();
                foreach (var model in models)
                {
                    var temp = oldPermission.FirstOrDefault(f => f.MenuPermissionID == model.MenuPermissionID);
                    if (temp == null)
                    {
                        inserts.Add(new SysUserMenuPermission { UserID = userId, MenuPermissionID = model.MenuPermissionID, Check = model.Check, Indeterminate = model.Indeterminate });
                    }
                    else
                    {
                        temp.Check = model.Check;
                        temp.Indeterminate = model.Indeterminate;
                        updates.Add(temp);
                    }
                }

                #endregion

                try
                {
                    unit.BeginTransaction();
                    if (inserts.Count() > 0) { rep.EntitiesAdded(inserts); }
                    if (updates.Count() > 0) { rep.EntitiesModified(updates); }
                    var msg = new string[] { "更新成功!", "更新失败!" };
                    return new OperationResult(unit.Commit() > 0, msg).SerializeToJsonResult();
                }
                catch (DataAccessException ex)
                {
                    unit.Rollback();
                    throw ExceptionHelper.ThrowServiceException(ex.Message);
                }
            }
        }

        #endregion

        /// <summary>
        /// 计算checkbox状态。0表示，不选中；1表示，选中；2表示，选中不打勾
        /// </summary>
        /// <param name="check">打勾状态</param>
        /// <param name="indeterminate">选中状态</param>
        /// <returns></returns>
        private int GetCheckboxState(bool check, bool indeterminate)
        {
            if (!check && !indeterminate) { return 0; }
            else if (check && !indeterminate) { return 1; }
            else if (check && indeterminate) { return 2; }

            return 0;
        }
    }
}
